<?php

namespace App\Controllers;

use Framework\Database;
use Framework\Validation;

class ListingController
{
    protected $db;

    public function __construct(){
        $config=require basePath('config/db.php');
        $this->db=new Database($config);
    }

    public function index(){
        $listings=$this->db->query('SELECT * FROM listing')->fetchAll();

        loadView('listings/index',[
            'listings'=>$listings
        ]);
    }

    public function create()
    {
        loadView('listings/create');
    }

    public function show($params){
        $id=$params['id'] ?? '';

        $params=[
            'id'=>$id
        ];

        $listing=$this->db->query('SELECT * FROM listing WHERE id=:id',$params)->fetch();

        if(!$listing){
            ErrorController::notFound('该岗位不存在！');
            return;
        }

        loadView('listings/show',[
            'listing'=>$listing
        ]);
    }

    /**
     * 在数据库中存储数据
     * 
     * @return void 该函数没有返回值。
     */
    public function store()
    {
        $allowedFields=['title','description','salary','tags','company','address','city','province','phone','email','requirements','benefits'];

        //从$_POST中提取允许的字段
        $newListingData=array_intersect_key($_POST,array_flip($allowedFields));

        //设置用户ID
        $newListingData['user_id']=1;

        //清洗数据
        $newListingData=array_map('sanitize',$newListingData);

        //定义必须的字段
        $requiredFields=['title','description','email','city','province'];

        //检查必须的字段
        $errors=[];
        foreach($requiredFields as $field){
            if(empty($newListingData[$field]) || !Validation::string($newListingData[$field])){
                $errors[$field]=ucfirst($field) . ' 为必须项';
            }
        }

        //处理可能的错误
        if(!empty($errors)){
            //如果有错误，重新加载创建列表的视图并显示错误
            loadView('listings/create',[
                'errors'=>$errors,
                'listing'=>$newListingData
            ]);
        }else{
            //初始化一个数据来收集所有字段名称，为构建SQL查询做准备
            $fields=[];

            //遍历$newListingData 数据，收集字段名称
            foreach($newListingData as $field=>$value){
                //向$fields 数据的末尾添加一个新元素
                $fields[]=$field;
            }

            //使用implode 函数将字段名称数据转换为字符串，用逗号分隔
            $fields=implode(',',$fields);

            //初始化一个数组来收集对应的占位符
            $values=[];

            //遍历$newsListingData数据，为每个字段生成一个占位符，并处理空字符串为null
            foreach($newListingData as $field=>$value){
                if($value===''){
                    $newListingData[$field]=null;
                }
                $values[]=':'.$field;
            }

            //使用implode 函数将占位符数组转换为字符串，用逗号分隔
            $values=implode(',',$values);

            //构建SQL插入语句
            $query="INSERT INTO listing ({$fields}) VALUES ({$values})";

            //执行SQL插入操作
            $this->db->query($query,$newListingData);

            //重定向到列表页面
            redirect('/listings');

        }
    }

    /**
     * 删除一个列表项
     * 
     * @param array $params 包含必要参数的数组，如列表项的ID。
     * @return void 该方法没有返回值。
     */
    public function destroy($params)
    {
        //从参数中获取列表项的ID
        $id=$params['id'];

        //准备用于数据库查询的参数
        $params=[
            'id'=>$id
        ];

        //查询数据库以确认列表项是否存在
        $listing=$this->db->query('SELECT * FROM listing WHERE id = :id',$params)->fetch();

        //如果查询结果为空，即列表项不存在
        if(!$listing){
            //调用错误控制器处理找不到列表项的情况
            ErrorController::notFound('职位不存在！');
            return;
        }

        //执行删除操作
        $this->db->query('DELETE FROM listing WHERE id= :id',$params);

        //设置提示信息
        $_SESSION['success_message']='删除职位成功！';

        //删除成功后重定向到列表页面
        redirect('/listings');
    }

    /**
     * 显示列表项编辑表单
     * 
     * @param array $params 包含必要参数的数组，例如列表项的ID
     * @return void 该方法没有返回值。
     */
    public function edit($params)
    {
        //尝试从参数中获取ID，如果没有提供，则默认为空字符串
        $id=$params['id'] ?? '';

        //准备用于数据库查询的参数
        $params=[
            'id'=>$id
        ];

        //查询数据库，获取指定ID的列表项数据
        $listing=$this->db->query('SELECT * FROM listing WHERE id= :id',$params)->fetch();

        //检查查询结果，确保列表项存在
        if(!$listing){
            //如果未找到列表项，调用错误控制器并返回
            ErrorController::notFound('职位不存在！');
            return;
        }

        //如果列表项存在，加载编辑视图并传递列表项数据
        loadView('listings/edit',[
            'listing'=>$listing
        ]);
    }

    /**
     * 更新列表项数据
     * 
     * @param array $params 包含必要参数的数组，例如列表项的ID
     * @return void 该方法没有返回值,成功执行会重定向，失败则重新加载编辑视图
     */
    public function update($params)
    {
        //尝试从参数中获取ID，如果没有提供，则默认为空字符串
        $id=$params['id'] ?? '';

        //准备用于数据库查询的参数
        $params=[
            'id'=>$id
        ];

        //查询数据库，获取指定ID的列表项数据
        $listing=$this->db->query('SELECT * FROM listing WHERE id= :id',$params)->fetch();

        //如果列表项不存在
        if(!$listing){
            //调用错误控制器并结束方法执行
            ErrorController::notFound('职位不存在！');
            return;
        }

        //定义可以从表单接受的字段列表
        $allowedFields=['title','description','salary','tags','company','address','city','province','phone',
        'email','requirements','benefits'];

        //过滤并仅保留允许的字段
        $updateValues=array_intersect_key($_POST,array_flip($allowedFields));

        //对过滤后的数据进行清洗
        $updateValues=array_map('sanitize',$updateValues);

        //定义必须填写的字符列表
        $requiredFields=['title','description','salary','email','city','province'];

        //初始化错误收集数组
        $errors=[];

        //检查必填字段是否已填写且符合要求
        foreach($requiredFields as $field){
            if(empty($updateValues[$field]) || !Validation::string($updateValues[$field])){
                $errors[$field]=ucfirst($field) . ' 为必填项！';
            }
        }

        //如果存在错误
        if(!empty($errors)){
            //重新加载编辑视图并传递错误信息与当前列表数据
            loadView('listings/edit',[
                'listing'=>$listing,
                'errors'=>$errors
            ]);
            exit;
        }else{
            //构建SQL更新语句中的字段赋值部分
            $updateFields=[];
            foreach(array_keys($updateValues) as $field){
                $updateFields[]="{$field} = :{$field}";
            }

            //将字段赋值部分合成字符串
            $updateFields=implode(', ',$updateFields);

            //构建完整的SQL更新语句
            $updateQuery="UPDATE listing SET $updateFields WHERE id=:id";

            //在更新数据中包括ID
            $updateValues['id']=$id;
            //执行SQL更新操作
            $this->db->query($updateQuery,$updateValues);

            //设置成功信息
            $_SESSION['success_message']='职位信息已更新！';

            //重定向到列表项详细页面
            redirect("/listings/" . $id);
        }
    }



}